use std::sync::Arc;

use async_trait::async_trait;
use common::{
    service::ServiceKey,
    protocol::{get_version, protocol_v1::ProtocolV1Reader, MsgType, XID},
};

use semver::Version;

use crate::protocol::{self, MsgPriority};



/**
 * Service
 */

#[async_trait]
pub trait Service: Send + Sync {
    /**
     * id
     */
    fn id(&self) -> i64;
    /**
     * 获取版本号, 返回的是序列化后的 protobuf 格式的字符串
     */
    fn version(&self) -> Version;

    fn name(&self) -> &str;

    /**
     * 初始化, 此时还不能接受任务
     */
    fn init(&self, config: &str);


    /**
     * 通知消息进来
     */
    
    fn message_in(&self, msg_buffer: &Vec<u8>) -> bool {
        let protocol_version = get_version(msg_buffer);
        match protocol_version {
            1 => {
                let reader = ProtocolV1Reader::new(msg_buffer);
                let xid = reader.xid();
                let msg_type = reader.msg_type();

                if msg_type.is_none() {
                    return false;
                }
                // 分配消息
                match msg_type.unwrap() {
                    MsgType::System => {
                        self.dispatch_message_with_pri(MsgPriority::Hig, xid);
                    }

                    MsgType::RspNormalMsg => {
                        self.dispatch_message_with_pri(MsgPriority::Normal, xid);
                    }
                    _ => {
                        self.dispatch_message_with_pri(MsgPriority::Low, xid);
                    }
                }

                true
            }
            _ => false,
        }
    }

    fn dispatch_message_with_pri(&self, pri: MsgPriority, xid: XID);

    /**
     * 主动关闭
     */
    async fn stop(&self);

    /**
     * 终结
     */
    fn finalize(&self);

    fn get_service_key(&self) -> ServiceKey;
    /**
     * 执行并行任务
     */
    fn execute_parallel_task(&self, task_id: i64) -> bool;
    /**
     * 禁止注册
     */
    fn disable_register(&self);
    /**
     * 判断是否需要注册
     */
    fn is_register(&self) -> bool;
    /**
     * 设置私有
     */
    fn set_private(&self, private: bool);
    /**
     * 是否是公有的
     */
    fn is_public(&self) -> bool;

    /**
     *
     */
    fn set_master_id(&mut self, master_id: i64);
    /**
     *
     */
    fn master_id(&self) -> i64;
    /**
     * 在线时间
     */
    fn oline_time(&self) -> i64;
    /**
     *
     */
    fn set_token_id(&self, token_id: i64);
    /**
     *
     */
    fn token_id(&self) -> i64;
}
